import React, { useEffect, useRef, useState, useCallback } from "react";

interface WaterfallProps<T> {
  dataList: T[];
  columns?: number;
  columnGap?: number;
  rowGap?: number;
  renderItem: (item: T, index: number) => React.ReactNode;
  onLoadMore?: () => void;
  hasMore?: boolean;
  threshold?: number;
  // 新增：获取图片宽高比的函数
  getAspectRatio: (item: T) => number;
}

function Waterfall<T>({
  dataList,
  columns = 2,
  columnGap = 16,
  rowGap = 16,
  renderItem,
  onLoadMore,
  hasMore = false,
  threshold = 100,
  getAspectRatio,
}: WaterfallProps<T>) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [columnHeights, setColumnHeights] = useState<number[]>([]);
  const [renderedItems, setRenderedItems] = useState<React.ReactNode[]>([]);

  const updateLayout = useCallback(() => {
    if (!containerRef.current) return;

    const containerWidth = containerRef.current.offsetWidth;
    const columnWidth = (containerWidth - (columns - 1) * columnGap) / columns;
    const heights = new Array(columns).fill(0);
    const items: React.ReactNode[] = [];

    dataList.forEach((item, index) => {
      const aspectRatio = getAspectRatio(item);
      const itemHeight = columnWidth / aspectRatio;

      const minHeight = Math.min(...heights);
      const minHeightIndex = heights.indexOf(minHeight);
      const left = minHeightIndex * (columnWidth + columnGap);
      const top = minHeight + (minHeight > 0 ? rowGap : 0);

      const itemElement = (
        <div
          key={index}
          style={{
            position: "absolute",
            left,
            top,
            width: columnWidth,
            height: itemHeight,
            transition: "opacity 0.3s",
          }}
        >
          {renderItem(item, index)}
        </div>
      );

      items.push(itemElement);
      heights[minHeightIndex] = top + itemHeight;
    });

    setColumnHeights(heights);
    setRenderedItems(items);
  }, [dataList, columns, columnGap, rowGap, renderItem, getAspectRatio]);

  useEffect(() => {
    updateLayout();
    window.addEventListener("resize", updateLayout);
    return () => window.removeEventListener("resize", updateLayout);
  }, [dataList, updateLayout]);

  useEffect(() => {
    const handleScroll = () => {
      if (!hasMore || !onLoadMore || !containerRef.current) return;

      const containerBottom =
        containerRef.current.getBoundingClientRect().bottom;
      const windowHeight = window.innerHeight;

      if (containerBottom - windowHeight <= threshold) {
        onLoadMore();
      }
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, [hasMore, onLoadMore, threshold]);

  return (
    <div
      ref={containerRef}
      style={{
        position: "relative",
        minHeight: Math.max(...columnHeights),
      }}
    >
      {renderedItems}
      {hasMore && (
        <div
          style={{
            textAlign: "center",
            padding: "20px 0",
            clear: "both",
            position: "absolute",
            bottom: -50,
            width: "100%",
          }}
        >
          加载中...
        </div>
      )}
    </div>
  );
}

export default Waterfall;
